package com.hzy.generation.service.impl;

import com.hzy.generation.domain.dto.GenForm;
import com.hzy.generation.service.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;

/**
 * <p>
 * 代码生成器实现类
 * freemarker 文档地址: http://www.freemarker.net/#4
 * </p>
 *
 * @author hzy
 * @since 2020-04-28
 */
@Service
public class GenServiceImpl implements IGenService {
    //domain 模板文件
    private final String templateDomain = "domain.ftl";
    private final String templateMapper = "mapper.ftl";
    private final String templateMapperXml = "mapperXml.ftl";
    private final String templateService = "service.ftl";
    private final String templateServiceImpl = "serviceImpl.ftl";
    private final String templateController = "controller.ftl";
    private final String templateServiceJs = "serviceJs.ftl";
    private final String templateIndexVue = "indexVue.ftl";
    private final String templateInfoVue = "infoVue.ftl";

    private final Configuration configuration;
    private final IGenDomainService genDomainService;
    private final IGenMapperService genMapperService;
    private final IGenMapperXmlService genMapperXmlService;
    private final IGenServiceService genServiceService;
    private final IGenServiceImplService genServiceImplService;
    private final IGenControllerService genControllerService;
    private final IGenServiceJsService genServiceJsService;
    private final IGenIndexVueService genIndexVueService;
    private final IGenInfoVueService genInfoVueService;

    public GenServiceImpl(IGenDomainService genDomainService,
                          IGenMapperService genMapperService,
                          IGenMapperXmlService genMapperXmlService,
                          IGenServiceService genServiceService,
                          IGenServiceImplService genServiceImplService,
                          IGenControllerService genControllerService,
                          IGenServiceJsService genServiceJsService,
                          IGenIndexVueService genIndexVueService,
                          IGenInfoVueService genInfoVueService) throws IOException {

        this.genDomainService = genDomainService;
        this.genMapperService = genMapperService;
        this.genMapperXmlService = genMapperXmlService;
        this.genServiceService = genServiceService;
        this.genServiceImplService = genServiceImplService;
        this.genControllerService = genControllerService;
        this.genServiceJsService = genServiceJsService;
        this.genIndexVueService = genIndexVueService;
        this.genInfoVueService = genInfoVueService;
        //第一步：创建一个Configuration对象，直接new一个对象。构造方法的参数就是FreeMarker对于的版本号。
        configuration = new Configuration(Configuration.getVersion());

        this.init();
    }

    private void init() throws IOException {
        //获取当前 class 所处的磁盘路径
        ApplicationHome applicationHome = new ApplicationHome(getClass());

        // 第二步：设置模板文件所在的路径。
        configuration.setDirectoryForTemplateLoading(new File(applicationHome + "/templates"));

        // 第三步：设置模板文件使用的字符集。一般就是utf-8.
        configuration.setDefaultEncoding("utf-8");
    }

    /**
     * 生成 domain
     *
     * @return
     */
    @Override
    public String genDomain(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateDomain);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genDomainService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 mapper
     *
     * @return
     */
    @Override
    public String genMapper(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateMapper);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genMapperService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 mapperXml
     *
     * @return
     */
    @Override
    public String genMapperXml(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateMapperXml);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genMapperXmlService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 service
     *
     * @return
     */
    @Override
    public String genService(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateService);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genServiceService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 service impl
     *
     * @return
     */
    @Override
    public String genServiceImpl(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateServiceImpl);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genServiceImplService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 controller
     *
     * @return
     */
    @Override
    public String genController(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateController);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genControllerService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 service js
     *
     * @return
     */
    @Override
    public String genServiceJs(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateServiceJs);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genServiceJsService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 index vue
     *
     * @return
     */
    @Override
    public String genIndexVue(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateIndexVue);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genIndexVueService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

    /**
     * 生成 info vue
     *
     * @return
     */
    @Override
    public String genInfoVue(GenForm form) throws IOException, TemplateException {
        // 第四步：加载一个模板，创建一个模板对象。
        Template template = configuration.getTemplate(this.templateInfoVue);

        //生成
        StringWriter stringWriter = new StringWriter();
        template.process(genInfoVueService.getGenContext(form), stringWriter);
        String result = stringWriter.toString();
        stringWriter.flush();
        stringWriter.close();
        return result;
    }

}
